from datetime import datetime, timedelta
from typing import Optional, Dict, Any
from jose import JWTError, jwt
from pydantic import BaseModel

# 配置（实际项目中应放在环境变量，避免硬编码）
SECRET_KEY = "your-secret-key-keep-it-safe-and-long-enough"  # 生产环境用强随机密钥
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30  # token有效期30分钟


# Token数据模型（包含用户ID）
class TokenPayload(BaseModel):
    user_id: int

def create_access_token(data: Dict[str, Any], expires_delta: Optional[timedelta] = None) -> str:
    """生成JWT令牌"""
    to_encode = data.copy()
    if expires_delta:
        expire = datetime.utcnow() + expires_delta
    else:
        expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    to_encode.update({"exp": expire})
    encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
    return encoded_jwt

def verify_token(token: str) -> TokenPayload:
    """验证JWT令牌并返回载荷（包含user_id）"""
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        user_id: int = payload.get("sub")  # "sub"字段存储用户ID
        if user_id is None:
            raise JWTError("Token contains no user ID")
        return TokenPayload(user_id=user_id)
    except JWTError:
        raise  # 抛出错误由调用方处理
